package com.cloud.sms.utils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.CheckedOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang.StringUtils;

/**
 * ZIP压缩工具(Java原生实现 )
 * 
 * @author ruanpeng
 * @since 1.0
 */
public class ZipUtils {

	private static final int BUFFER = 1024;
	// 压缩文件的后缀
	public static final String EXT = ".zip";

	/**
	 * 压缩文件
	 * 
	 * @param srcPath
	 *            源文件路径 + 文件名
	 * @param destPath
	 *            生成压缩文件存放的路径（如为空，则生成到源文件的同一路径下）
	 * @param destFileName
	 *            生成压缩文件的文件名（如为空，则是在源文件的后面加上.zip）
	 * @throws Exception
	 */
	public static void compress(String srcPath, String destPath, String destFileName) throws Exception {
		File srcFile = new File(srcPath);
		if (!StringUtils.isNotEmpty(destFileName)) {
			destFileName = srcFile.getName();
		}
		if (!StringUtils.isNotEmpty(destPath)) {
			destPath = srcFile.getParent();
		}
		File f = new File(destPath);
		// 当文件夹不存在时，先建立文件夹
		if (!f.exists() || !f.isDirectory()) {
			f.mkdir();
		}
		String destFile = destPath + "/" + destFileName + EXT;
		compress(srcFile, new File(destFile));
	}

	/**
	 * 压缩文件
	 * 
	 * @param srcFile
	 *            源文件 （如：c:/aa.jpg）
	 * @param destFile
	 *            目标文件（如：c:/aa.jpg）
	 * @throws Exception
	 */
	public static void compress(File srcFile, File destFile) throws Exception {
		// 对输出文件做CRC32校验
		CheckedOutputStream cos = new CheckedOutputStream(new FileOutputStream(destFile), new CRC32());

		ZipOutputStream zos = new ZipOutputStream(cos);
		compressFile(srcFile, zos);
		zos.flush();
		zos.close();
	}

	/**
	 * 压缩文件
	 * 
	 * @param srcFile
	 *            源文件 （如：c:/aa.jpg）
	 * @param zos
	 *            流
	 * @throws Exception
	 */
	private static void compressFile(File srcFile, ZipOutputStream zos) throws Exception {
		// srcFile.getName()是指zip文件里所包含的文件的名字
		ZipEntry entry = new ZipEntry(srcFile.getName());
		zos.putNextEntry(entry);

		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(srcFile));
		int count;
		byte data[] = new byte[BUFFER];
		while ((count = bis.read(data, 0, BUFFER)) != -1) {
			zos.write(data, 0, count);
		}
		bis.close();
		zos.closeEntry();
	}

	/**
	 * 解压缩文件
	 * 
	 * @param srcFileStr
	 *            需要解压缩的文件
	 * @param destPath
	 *            解压缩后存放的路径
	 * @throws Exception
	 */
	private static String unCompress(String srcFileStr, String destPath) throws Exception {
		// 要解压缩的文件
		File file = new File(srcFileStr);

		CheckedInputStream cis = new CheckedInputStream(new FileInputStream(file), new CRC32());
		ZipInputStream zis = new ZipInputStream(cis);

		String errTip = "";
		ZipEntry entry = null;
		while ((entry = zis.getNextEntry()) != null) {

			if (entry.isDirectory()) {
				// if (!destFile.exists()) {
				// destFile.mkdirs();
				// }
			} else {
				// 解压缩后存放的目标 文件
				String fileName = entry.getName();
				fileName = fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length());

				String destFileStr = destPath + File.separator + fileName;
				File destFile = new File(destFileStr);

				if (destFile.exists() && destFile.isFile()) {
					errTip += "文件：" + destFileStr + " 已存在。";
				} else {
					if (!destFile.getParentFile().exists()) {
						destFile.getParentFile().mkdirs();
					}

					BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(destFile));
					int count;
					byte data[] = new byte[BUFFER];
					while ((count = zis.read(data, 0, BUFFER)) != -1) {
						bos.write(data, 0, count);
					}

					bos.close();
				}
			}
		}
		cis.close();
		zis.closeEntry();
		return errTip;
	}

	public static void main(String[] arg) throws Exception {
		// 压缩文件
		// ZipUtils.compress("c://hp.jpg", "", "");

		// 解压缩文件
		System.out.println("=====" + ZipUtils.unCompress("c:/upload.zip", "c:/ccc"));
	}
}